package com.longyiqun.apitest;

import com.aventstack.extentreports.ExtentReports;
import com.aventstack.extentreports.ExtentTest;
import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestResult;

/**
 * program: ApiTest
 * package: com.longyiqun.apitest
 * author: 龙轶群
 * create: 2018-04-16 11:11
 **/

public class ExtentTestNGITestListener implements ITestListener {
    private static ExtentReports extent = ExtentManager.createInstance("extent-api.html");
    private static ThreadLocal<ExtentTest> parentTest = new ThreadLocal();
    private static ThreadLocal<ExtentTest> test = new ThreadLocal();

    @Override
    public synchronized void onStart(ITestContext context) {
//        ExtentTest parent = extent.createTest(getClass().getName());
//        parentTest.set(parent);
    }

    @Override
    public synchronized void onFinish(ITestContext context) {
        extent.flush();
    }

    @Override
    public synchronized void onTestStart(ITestResult result) {

        // 多数注释均为解决怎么把TestName可参数化, 依然没成功

//        ExtentTest child = parentTest.get().createNode(result.getMethod().getMethodName());
//        test.set(child);



        //setTestNameInXml(result);


        test.set(extent.createTest(result.getMethod().getMethodName()));

        //test.set(extent.createTest(reallyName));


//        if (result.getMethod().getMethodName() == "testRunAll") {
//
//        } else {
//
//            test.set(extent.createTest(result.getMethod().getMethodName()));
//            //ExtentTest child = parentTest.get().createNode(result.getMethod().getMethodName());
//            //test.set(child);
//        }
    }

//    private void setTestNameInXml(ITestResult tr) {
//        try
//        {
//            ITestContext ctx = tr.getTestContext();
//            Set<String> attribs = ctx.getAttributeNames();
//
//            for ( String x : attribs ) {
//                if (x.contains("testName")) {
//
//                    Field method = TestResult.class.getDeclaredField("m_method");
//                    method.setAccessible(true);
//                    method.set(tr, tr.getMethod().clone());
//                    Field methodName = BaseTestMethod.class.getDeclaredField("m_methodName");
//                    methodName.setAccessible(true);
//                    methodName.set(tr.getMethod(), ctx.getAttribute( x ));
//                }
//            }
//        }
//
//        catch (Exception e)
//        {
//            e.printStackTrace();
//        }
//    }

    /*当成功的时候, 只需要返回Pass字样即可*/
    @Override
    public synchronized void onTestSuccess(ITestResult result) {

        // 自定义Attribute
        String jsonReturnAttribute = "";
        String parmsInAttribute = "";
        String chineseAttribute = "";
        String urlAttribute = "";
        String moduleAttribute = "";
        String verifyStringAttribute = "";


        // 如果没获取到需要判断一下
        if (!result.getAttributeNames().contains("jsonReturn")) {
            jsonReturnAttribute = "未获取到返回值";
        } else {
            jsonReturnAttribute = result.getAttribute("jsonReturn").toString();
        }

        if (!result.getAttributeNames().contains("parmsIn")) {
            parmsInAttribute = "无入参";
        } else {
            parmsInAttribute = result.getAttribute("parmsIn").toString();
        }

        if (!result.getAttributeNames().contains("chinese")) {
            chineseAttribute = "无中文说明";
        } else {
            chineseAttribute = result.getAttribute("chinese").toString();
        }

        if (!result.getAttributeNames().contains("caseUrl")) {
            urlAttribute = "无URL";
        } else {
            urlAttribute = result.getAttribute("caseUrl").toString();
        }

        if (!result.getAttributeNames().contains("caseModule")) {
            moduleAttribute = "无模块";
        } else {
            moduleAttribute = result.getAttribute("caseModule").toString();
        }

        if (!result.getAttributeNames().contains("verifyString")) {
            verifyStringAttribute = "无验证规则";
        } else {
            verifyStringAttribute = result.getAttribute("verifyString").toString();
        }

        // 自定义返回成功的结果集
        ((ExtentTest)test.get()).pass("<h4>" + result.getAttribute("caseName") + "</h4><br/>中文说明: " + chineseAttribute + "<br/>URL: " + urlAttribute + "<br/>模块: " + moduleAttribute + "<br/>验证规则: " + verifyStringAttribute + "<br/><br/>入参: <br/>" + parmsInAttribute + "<br/>" + "<br/>返回: <br/>" + jsonReturnAttribute);
    }

    /*当失败的时候, 自定义失败的Message以及自定义的报告结果*/
    @Override
    public synchronized void onTestFailure(ITestResult result) {

        // 自定义Attribute
        String jsonReturnAttribute = "";
        String parmsInAttribute = "";
        String chineseAttribute = "";
        String urlAttribute = "";
        String moduleAttribute = "";
        String verifyStringAttribute = "";


        // 如果没获取到需要判断一下
        if (!result.getAttributeNames().contains("jsonReturn")) {
            jsonReturnAttribute = "未获取到返回值";
        } else {
            jsonReturnAttribute = result.getAttribute("jsonReturn").toString();
        }

        if (!result.getAttributeNames().contains("parmsIn")) {
            parmsInAttribute = "无入参";
        } else {
            parmsInAttribute = result.getAttribute("parmsIn").toString();
        }

        if (!result.getAttributeNames().contains("chinese")) {
            chineseAttribute = "无中文说明";
        } else {
            chineseAttribute = result.getAttribute("chinese").toString();
        }

        if (!result.getAttributeNames().contains("caseUrl")) {
            urlAttribute = "无URL";
        } else {
            urlAttribute = result.getAttribute("caseUrl").toString();
        }

        if (!result.getAttributeNames().contains("caseModule")) {
            moduleAttribute = "无模块";
        } else {
            moduleAttribute = result.getAttribute("caseModule").toString();
        }

        if (!result.getAttributeNames().contains("verifyString")) {
            verifyStringAttribute = "无验证规则";
        } else {
            verifyStringAttribute = result.getAttribute("verifyString").toString();
        }

        // 失败结果
        String failMessage = result.getThrowable().getMessage();

        // 自定义返回失败的结果集
        ((ExtentTest)test.get()).fail("<h4>" + result.getAttribute("caseName") + "</h4><br/>中文说明: " + chineseAttribute + "<br/>URL: " + urlAttribute + "<br/>模块: " + moduleAttribute + "<br/>验证规则: " + verifyStringAttribute + "<br/><br/><p style='color:red'>失败原因: " + failMessage + "<br/></p><br/>" + "返回JSON:" + "<br/>" + jsonReturnAttribute + "<br/><br/>" + "输入参数: " + "<br/>" + parmsInAttribute);
    }

    @Override
    public synchronized void onTestSkipped(ITestResult result) {
        ((ExtentTest)test.get()).skip(result.getThrowable());
    }

    @Override
    public synchronized void onTestFailedButWithinSuccessPercentage(ITestResult result) {

    }
}
